/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights
 * reserved. <a>http://www.cqcis.com</a>
 */
package com.cqcis.uip.base.framework.service.impl;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

import org.apache.mina.common.IoFuture;
import org.apache.mina.common.IoFutureListener;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
import org.apache.mina.common.WriteFuture;
import org.eclipse.osgi.framework.console.CommandInterpreter;
import org.eclipse.osgi.framework.console.CommandProvider;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;

import com.cqcis.uip.base.framework.FrameworkConstants;
import com.cqcis.uip.base.framework.UIPServiceException;
import com.cqcis.uip.base.framework.base.adaptor.AbstractSocketService;
import com.cqcis.uip.base.framework.common.ControlMsg;
import com.cqcis.uip.base.framework.common.HttpParam;
import com.cqcis.uip.base.framework.common.OperatorLog;
import com.cqcis.uip.base.framework.common.Task;
import com.cqcis.uip.base.framework.common.TelnetCommand;
import com.cqcis.uip.base.framework.core.RegisteredService;
import com.cqcis.uip.base.framework.core.RegisteredServiceFindService;
import com.cqcis.uip.base.framework.core.cluster.ClusterCommandSupport;
import com.cqcis.uip.base.framework.core.cluster.ClusterTaskProcessor;
import com.cqcis.uip.base.framework.core.cluster.ClusterTaskProcessorImpl;
import com.cqcis.uip.base.framework.core.impl.AutoInjectServiceBeanPostProcessor;
import com.cqcis.uip.base.framework.utils.StringUtil;
import com.cqcis.uip.base.framework.utils.TimeUtil;
import com.cqcis.uip.base.framework.utils.LogServiceThreadPoolExecutor.LogThreadPoolExecutor;

/**
 * telnet控制服务, 提供远程登录到接口平台，控制、察看各接口的功能
 * 
 * @author huangmy
 * @date   2008-4-6
 */
public class TelnetConsoleServiceImpl extends IoHandlerAdapter {	
	private final static String REGISTERSERVICEPRINTLOGCONSOLE_KEY = "REGISTERSERVICEPRINTLOGCONSOLE_KEY";
	private ServiceTracker cptracker; // 所有的命令服务
	private BundleContext bundleContext;
	private final static String NEWLINE = "\r\n";
	private final static String CONSOLEPROMPT = NEWLINE + "uip> ";
	private Map<IoSession, Long> execExclusionCmdSessions = new HashMap<IoSession, Long>();
	private final static long EXCLUSION_TIMEOUT = 30 * 60 * 1000; //30分钟
	private final static String EXCLUSION_CMD = "EXCLUSION_CMD";	
	protected final static String UPKEY_VALUE1 = "[A"; // 向上控制键
	protected final static String LEFTKEY_VALUE = "[B"; // 向左控制键
	protected final static String RIGHTKEY_VALUE = "[C"; // 向右控制键
	protected final static String DOWNKEY_VALUE = "[D"; // 向下控制键
	private final static String UP_COMMAND_HISTORY = "UP_COMMAND_HISTORY";
	private final static String LOGIN = TelnetConsoleServiceImpl.class.getName() + "_LOGIN";
	private Object sessionLock = new Object();
	private LogThreadPoolExecutor sessionThreadModelExecutor;// session tpe
	private ClusterTaskProcessor clusterTaskProcessor;
			
	public TelnetConsoleServiceImpl(BundleContext bundleContext, LogThreadPoolExecutor sessionThreadModelExecutor) {
		this.bundleContext = bundleContext;
		this.sessionThreadModelExecutor = sessionThreadModelExecutor;
		this.clusterTaskProcessor = new ClusterTaskProcessorImpl(bundleContext);
	}
	
	/**
	 * 获取所有的命令服务
	 * 
	 * @return
	 */
	private CommandProvider[] getAllCommandServices() {
		ServiceReference[] srs = this.cptracker.getServiceReferences();
		if (srs != null) {
			CommandProvider[] cps = new CommandProvider[srs.length];
			for (int i = 0; i < srs.length; i ++) {
				ServiceReference sr = srs[i];
				cps[i] = (CommandProvider)this.bundleContext.getService(sr);
			}
			
			return cps;
		}
		
		return new CommandProvider[0];
	}
	
	/**
	 * 注册服务查找
	 * 
	 * @return
	 */
	private RegisteredServiceFindService getRegisteredServiceFindService() {
		ServiceReference sr = this.bundleContext.getServiceReference(RegisteredServiceFindService.class.getName());
		if (sr != null) {
			return (RegisteredServiceFindService)this.bundleContext.getService(sr);
		}
		
		return null;
	}
		
	public void start() throws Exception {		
		File file = new File(UserEncryption.ENCR_FILE);
		boolean hasAdmin = false;
		UserEncryption adminUe = new UserEncryption();
		adminUe.userId = 0;
		adminUe.userName = "admin";
		adminUe.password = "admin";
		adminUe.changed = true;
		if (!file.exists()) {
			hasAdmin = false;
		}
		
		List<UserEncryption> ues = getCurrentUserEncryptions();
		if (ues == null) {
			hasAdmin = false;
		}
		
		if (ues != null) {
			for (UserEncryption ue : ues) {
				if (ue.userName.equalsIgnoreCase(adminUe.userName)) {
					hasAdmin = true;
				}
			}
		}
		
		if (!hasAdmin) {
			saveUserEncryption(adminUe);
		}
				
		this.cptracker = new ServiceTracker(this.bundleContext, CommandProvider.class.getName(), null);
		this.cptracker.open();		
	}
	
	public void stop() throws Exception {
		if (this.cptracker != null) {
			this.cptracker.close();
		}		
	}
	
	private enum LoginState {
		LOGGING_USER,
		LOGGING_PWD,
		LOGIN
	}
	
	private class User {
		LoginState state = LoginState.LOGGING_USER;
		String userName; 
		String password;
		String loginTime;
		
		@Override
		public String toString() {
			StringBuffer b = new StringBuffer();
			b.append("username: " + userName)
			 .append(", logintime: " + loginTime);
			
			return b.toString();
		}
	}
	
	private Long createSessionId(IoSession session) {
		long maxId = 0;
		
		synchronized (sessionLock) {
			Set<IoSession> ss = session.getService().getManagedSessions(session.getServiceAddress());
			if (ss != null) {
				for (IoSession s : ss) {
					Long id = (Long)s.getAttribute("_SESSION_ID_");
					if (id != null && id > maxId) {
						maxId = id;
					}
				}
			}
			
			maxId = maxId + 1;
		} 
		
		session.setAttribute("_SESSION_ID_", new Long(maxId));
		return maxId;
	}
	
	private IoSession getSessionFrom(IoSession session, long sid) {
		synchronized (sessionLock) {
			Set<IoSession> ss = session.getService().getManagedSessions(session.getServiceAddress());
			if (ss != null) {
				for (IoSession s : ss) {
					Long id = (Long)s.getAttribute("_SESSION_ID_");
					if (id != null && id == sid) {
						return s;
					}
				}
			}

			return null;
		} 
	}
	
	private long getSessionId(IoSession session) {
		Long id = (Long)session.getAttribute("_SESSION_ID_");
		if (id != null ) {
			return id;
		}
		
		return -1;
	}
	
	@Override
	public void sessionCreated(IoSession session) throws Exception {
		sessionMsgPrintln(session, "\t**** Universal Interface Platform ****");
		session.setAttribute(FrameworkConstants.TELNETFIRSTSEND_03, Boolean.TRUE);
		session.setAttribute(FrameworkConstants.INTERFACE_STREAM_RECORD_CLOSED, Boolean.TRUE);
		
		session.write(createCMDControlMsg(new TelnetCommand(TelnetCommand.WONT, (byte)0x01)));
		
		//FF FB 01 FF FD 1F FF FC  C8 FF FD 01
		
		createSessionId(session);
		
		if (session.getAttribute(LOGIN) == null) {
			session.setAttribute(LOGIN, new User());
			session.write(NEWLINE + "login: ");			
			return;
		}
				
		session.write(CONSOLEPROMPT);
	}
	
	/**
	 * 创建命令
	 * 
	 * @param rspCmd
	 * @return
	 */
	private ControlMsg createCMDControlMsg(TelnetCommand rspCmd) {
		ControlMsg cm = new ControlMsg();
		cm.setAttachement(rspCmd);
		cm.setControlMsg(false);
		return cm;
	}
	
	protected ControlMsg createCMDControlMsg(String key, Object value) {
		ControlMsg cm = new ControlMsg();
		cm.setAttachement(null);
		cm.setControlMsg(false);
		cm.setAttribute(key, value);
		return cm;
	}
	
	/**
	 * 校验用户的合法性
	 * 
	 * @param user
	 * @return true 通过 false 不通过
	 */
	private boolean checkForUser(User user) {
		String userName = user.userName;
		String password = user.password;
		
		List<UserEncryption> ues = getCurrentUserEncryptions();
		if (ues != null) {
			for (UserEncryption ue : ues) {				
				if (ue.userName.equalsIgnoreCase(userName) 
						&& (!StringUtil.hasText(ue.password) 
								|| ue.password.equals(getMessageDigest(userName, password)))) {
					// 通过
					return true;
				}
			}
		}
		
		return false;
	}
	
	private static List<UserEncryption> getCurrentUserEncryptions() {
        BufferedReader rd = null;
        List<UserEncryption> ues = new ArrayList<UserEncryption>();
		
		try {			
			rd = new BufferedReader(new FileReader(UserEncryption.ENCR_FILE));
			String line = null;
			while ((line = rd.readLine()) != null) {
				UserEncryption ue = parseUserEncryption(line);
				if (ue != null) {
					ues.add(ue);
				}				
			}			
		} catch (Throwable e) {		
			e.printStackTrace();
		} finally {
			if (rd != null) {
				try {
					rd.close();
				} catch (IOException e) {
				}
			}
		}
		
		return ues;
	}
		
	private void saveUserEncryption(UserEncryption ue) {		
		BufferedWriter bw = null;
		try {			
			bw = new BufferedWriter(new FileWriter(UserEncryption.ENCR_FILE, true));
			String line = encodeUserEncryption(ue);
			bw.append(line);	
			bw.newLine();
		} catch (Throwable e) {	
			throw new RuntimeException(e);
		} finally {
			if (bw != null) {
				try {
					bw.close();
				} catch (IOException e) {
				}
			}
		}
	}
	
	private static UserEncryption parseUserEncryption(String line) {		
		UserEncryption ue = new UserEncryption();
		String[] ss = new String[4];
		StringTokenizer st = new StringTokenizer(line, UserEncryption.SPLIT);
		
		ss[0] = st.hasMoreTokens() ? st.nextToken() : "";
		ss[1] = st.hasMoreTokens() ? st.nextToken() : "";
		ss[2] = st.hasMoreTokens() ? st.nextToken() : "";
		ss[3] = st.hasMoreTokens() ? st.nextToken() : "";
		
		if (ss == null || ss.length != 4) {
			throw new UIPServiceException("Invalid file encryption format.");
		}
		
		ue.userId = Long.valueOf(ss[0]);
		ue.userName = ss[1] == null ? "" : ss[1];
		ue.password = ss[2] == null ? "" : ss[2];
		String eis = ss[3] == null ? "" : ss[3];
		List<String> intfs = new ArrayList<String>();
		String[] execs = eis.split(UserEncryption.INTF_SP);
		if (execs != null) {
			for (String e : execs) {
				intfs.add(e);
			}
		}
		ue.execIntfs = intfs;
		
		return ue;
	}
	
	/**
	 * 信息摘要
	 * 
	 * @param username
	 * @param password
	 * @return
	 */
	private String getMessageDigest(String username, String password) {
		MessageDigest md;
		try {
			md = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			throw new RuntimeException(e);
		}
		
		username = StringUtil.trimWhiteToNull(username);
		password = StringUtil.trimWhiteToNull(password);
		password = (password == null) ? "" : password;
		
		byte[] bb = md.digest((username + password).getBytes());
				
		StringBuffer sb = new StringBuffer();
		for (byte b : bb) {
			sb.append(StringUtil.toHexString(b, false));
		}
		
		return sb.toString();
	}
	
	private String encodeUserEncryption(UserEncryption ue) {
		String password = ue.changed ? getMessageDigest(ue.userName, ue.password) : ue.password;
		
		StringBuffer b = new StringBuffer();
		b.append(ue.userId).append(UserEncryption.SPLIT)
		 .append(ue.userName).append(UserEncryption.SPLIT)
		 .append(password).append(UserEncryption.SPLIT);
		
		StringBuffer eb = new StringBuffer();		
		if (ue.execIntfs != null) {
			for (String e : ue.execIntfs) {
				eb.append(e).append(UserEncryption.INTF_SP);
			}
		}
		
		if (eb.length() <= 0) {
			eb.append(" ");
		}
		
		b.append(eb);
		b.append(UserEncryption.SPLIT);
		
		return b.toString();
	}
	
	/**
	 * 用户管理, 定义一个用户
	 * 
	 * @author huangmy
	 * @date   2008-9-16
	 */
	private static class UserEncryption {
		boolean changed;
		long userId;  // 用户ID
		String userName; // 用户名
		String password; // 用户密码
		List<String> execIntfs; // 可执行接口列表
		static String SPLIT = ",";
		static String INTF_SP = ";";
		static String ENCR_FILE = "../configuration/users.pwd";
		
		@Override
		public String toString() {
			StringBuffer b = new StringBuffer();
			b.append("UE:{userId=").append(userId)
			 .append(", userName=").append(userName)
			 .append(", password=").append(password)
			 .append(", execIntfs=").append(execIntfs);
			return b.toString();
		}
	}
	
	/**
	 * 添加uip用户：用户名, 密码
	 * 
	 * @param username
	 * @param password
	 */
	private void useradd(String username, String password) {
		long userId = createUserId(); // 先创建userId
		UserEncryption ue = new UserEncryption();
		ue.userId = userId;
		ue.userName = username;
		ue.password = password;
		ue.changed = true;
				
		saveUserEncryption(ue);
	}
	
	/**
	 * 删除用户
	 * 
	 * @param username
	 */
	private void userdelete(String username) {
		List<UserEncryption> ues = getCurrentUserEncryptions();
		if (ues != null) {	
			for (Iterator<UserEncryption> it = ues.iterator(); it.hasNext();) {
				UserEncryption ue = it.next();
				if (ue.userName.equalsIgnoreCase(username)) {
					it.remove();
				}
			}
			
			// 重写
			File file = new File(UserEncryption.ENCR_FILE);
			file.delete();
			for (Iterator<UserEncryption> it = ues.iterator(); it.hasNext();) {
				saveUserEncryption(it.next());
			}
		}
	}
	
	private List<String> getAllIntfIds() {
		List<String> intfs = new ArrayList<String>();
		RegisteredServiceFindService findService = getRegisteredServiceFindService();
		if (findService == null) {
			return intfs;
		}
				
		Collection<RegisteredService> rss = findService.getRegisteredServices();
		if (rss != null) {			
			for (RegisteredService rs : rss) {
				intfs.add(rs.getId());				
			}
		}
		return intfs;
	}
	
	/**
	 * 增加用户权限
	 * 
	 * @param username  用户名
	 * @param cmd       命令 add or delete
	 * @param intfId    接口ID
	 */
	private boolean userchmod(IoSession session, String username, String cmd, String intfId) {		
		List<UserEncryption> ues = getCurrentUserEncryptions();
		boolean changed = false;
		if (ues != null) {				
			for (UserEncryption ue : ues) {
				if (ue.userName.equalsIgnoreCase(username)) {
					// 修改
					if ("add".equalsIgnoreCase(cmd)) {
						if ("*".equalsIgnoreCase(intfId)) {
							ue.execIntfs.clear();
							ue.execIntfs.addAll(getAllIntfIds());
						} else if (!ue.execIntfs.contains(intfId)) {
							ue.execIntfs.add(intfId);
						}
					} else if ("del".equalsIgnoreCase(cmd)) {
                        if ("*".equalsIgnoreCase(intfId)) {
                        	ue.execIntfs.clear();
						} else {
						    ue.execIntfs.remove(intfId);
						}
					} else if ("password".equalsIgnoreCase(cmd)) {
						if (password(session, username, null, intfId, false)) {
						    changed = true;
						    return true;
						}
						return false;
					} else {
						throw new RuntimeException("Invalid subcmd， must be add or delete.");
					}
					
					changed = true;
				}
			}
			
			// 重写
			File file = new File(UserEncryption.ENCR_FILE);
			file.delete();
			for (Iterator<UserEncryption> it = ues.iterator(); it.hasNext();) {
				saveUserEncryption(it.next());
			}
		}
		
		if (!changed) {
			sessionMsgPrintln(session, "Command error, " 
					+ "USAGE: userchd 'username' add/del/password 'intfId'[newpassword]");
		}
		
		return changed;
	}
	
	/**
	 * 修改密码
	 * 
	 * @param username
	 * @param password
	 */
	private boolean password(IoSession session, String username, String oldpassword, 
			String newpassword, boolean direct) {
		User user = (User)session.getAttribute(LOGIN);
		boolean changed = false;
		List<UserEncryption> ues = getCurrentUserEncryptions();
		if (ues != null) {				
			for (UserEncryption ue : ues) {
				if (ue.userName.equalsIgnoreCase(username)) {
					if ("admin".equalsIgnoreCase(user.userName) && !direct) {
						ue.password = newpassword;						
					} else if (!StringUtil.hasText(ue.password) 
							|| ue.password.equalsIgnoreCase(getMessageDigest(username, oldpassword))) {
						ue.password = newpassword;
					} else {
						sessionMsgPrintln(session, "Password Error for user '" + username + "!");
						return false;
					}
					changed = true;
					ue.changed = true;
				}
			}
			
			// 重写
			File file = new File(UserEncryption.ENCR_FILE);
			file.delete();
			for (Iterator<UserEncryption> it = ues.iterator(); it.hasNext();) {
				saveUserEncryption(it.next());
			}
		}
		
		return changed;
	}
	
	/**
	 * 校验用户执行命令的合法性
	 * 
	 * @param username
	 * @param cmdline
	 * @return
	 */
	private boolean checkUserCmdPermission(String username, String command, String rsId) {
		if ("admin".equalsIgnoreCase(username)) {
			return true;
		}
		
		RegisteredServiceFindService findService = getRegisteredServiceFindService();
		if (findService == null) {
			return false;
		}
		
		RegisteredService rs = findService.getRegisteredService(Long.valueOf(rsId));
		if (rs == null) {
			return false;
		}
		
		rs.getAttributes().setAttribute(FrameworkConstants.RSOPERATOR_LOG, new OperatorLog(username, command, TimeUtil.getCurrentTime()));
		
		String intfId = rs.getId();
		
		List<UserEncryption> ues = getCurrentUserEncryptions();
		if (ues != null) {	
			for (UserEncryption ue : ues) {
				if (ue.userName.equalsIgnoreCase(username)) {
					for (String e : ue.execIntfs) {
						if (e.equalsIgnoreCase(intfId)) {
							return true;
						}
					}
					
					return false;
				}
			}
		}
		return false;
	}
	
	/**
	 * 创建userId
	 * 
	 * @return
	 */
	private long createUserId() {
		long userId = 0;
		long maxUserId = 0;
		
		List<UserEncryption> ues = getCurrentUserEncryptions();
		if (ues != null) {			
			for (UserEncryption ue : ues) {
				if (ue.userId > maxUserId) {
					maxUserId = ue.userId;
				}
			}
		}
		
		userId = maxUserId + 1;
				
		return userId;
	}
	
	/**
	 * 提交task
	 * 
	 * @param param
	 * @param session
	 */
	private void doForTaskSchedule(HttpParam param, IoSession session) {
		this.clusterTaskProcessor.doTaskSchedule(param, session);
	}
		
	@Override
	public void messageReceived(final IoSession session, Object message) throws Exception {
		if (message instanceof HttpParam && session.getAttribute(FrameworkConstants.CLUSTER_SWITCH) != null) {
			HttpParam param = (HttpParam)message;
			doForTaskSchedule(param, session);
			return;
		}
		
		User user = (User)session.getAttribute(LOGIN);
		if (user == null) {
			session.close();
			return;
		}
		
		ControlMsg msg = (ControlMsg)message;
		
		if (msg.getAttachement() != null) {
			// cmd
			return;
		}
		
		String cmdline = msg.getMessage();
		
		cmdline = StringUtil.trimWhiteToNull(cmdline);
		
		if (user.state == LoginState.LOGGING_USER) {	
			if (!StringUtil.hasText(cmdline)) {
				session.close();
				return;
			}
			user.userName = cmdline;// 用户名
			user.state = LoginState.LOGGING_PWD;
			session.write(createCMDControlMsg(new TelnetCommand(TelnetCommand.WILL, (byte)0x01)));
			session.write(user.userName + "'s Password: ");			
			return;
		} else if (user.state == LoginState.LOGGING_PWD) {
			user.password = cmdline; // 密码
			// 校验
			if (!checkForUser(user)) {
				// 不通过
				WriteFuture wf = session.write("Sorry, You entered an invalid login name or password!");
				wf.addListener(new IoFutureListener() {
					public void operationComplete(IoFuture future) {
						session.close();
					}
				});
				
				return;
			}
			session.write(createCMDControlMsg(new TelnetCommand(TelnetCommand.WONT, (byte)0x01)));
			// 通过
			user.state = LoginState.LOGIN;
			user.loginTime = TimeUtil.getCurrentTime();
			session.write(NEWLINE);
			session.write(CONSOLEPROMPT);
			return;
		}
				
		if ((cmdline = StringUtil.trimWhiteToNull(cmdline)) != null) {			
			docommand(cmdline, session);			
		}
		
		session.write(CONSOLEPROMPT);
	}
	
	@Override
	public void sessionClosed(IoSession session) throws Exception {
		// 独占退出
		_out(session);
		
		// 清理日志输出
		closeRsplcForSession(session);
	}
	
	@Override
	public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
		sessionPrint(session, "Exception Catch in Telnet Console.", cause, true, null);
		sessionClosed(session);
	}
	
	/**
	 * 执行命令
	 * 
	 * @param cmdline
	 */
	private void docommand(String cmdline, IoSession session) {		
		if (cmdline != null && cmdline.length() > 0) {
			if (cmdline.length() >= 2 && cmdline.charAt(0) == 91 && cmdline.charAt(cmdline.length() - 1) == 65) {
				String cmdHis = (String)session.getAttribute(UP_COMMAND_HISTORY);
				sessionMsgPrintln(session, cmdHis);
				executeCommand(cmdHis, session);
				return;
			}
			
			executeCommand(cmdline, session);
			session.setAttribute(UP_COMMAND_HISTORY, cmdline); // 保存为历史命令
		}
	}
	
	/**
	 * 执行命令
	 * 
	 * @param cmdline
	 */
	private void executeCommand(String cmdline, IoSession session) {
		StringBuffer msgBuf = new StringBuffer();
		CommandInterpreter intcp = new TelnetCommandInterpreter(cmdline, getAllCommandServices(), msgBuf);
		String command = intcp.nextArgument();
		if (command != null) {
			command = command.toLowerCase();
			if ("exit".equals(command) || "disconnect".equals(command)
					|| "shutdown".equals(command)
					|| "close".equals(command)
					|| "init".equals(command)) {
				if (session.getAttribute(FrameworkConstants.CLUSTER_SWITCH) == null) {
					session.close();
				}
				
				return;
			}
			
            User user = (User)session.getAttribute(LOGIN);
			
			if (!checkForCmdPermission(user.userName, command, cmdline)) {
				sessionMsgPrintln(session, "您没有权限执行该项操作.");
				return;
			}
			
			boolean executed = filterCommandExecute(command);
			if (!executed) {
				// 检查是否独占控制
				// 1. 先获取执行权限
				// 2. 执行
				if (!getExecuteExclusion(session, command)) {						
					return;
				}
			}
			
			// 优先命令处理
			if (processCommandFirst(session, command, intcp, cmdline)) {
				return;
			}
			
			intcp.execute(command);
		}
		
		// 替换"\n"字符为\r\n
		String msg = msgBuf.toString();
		
		ClusterCommandSupport ccs = new ClusterCommandSupport(cmdline);
		String[] args = ccs.getClusterArgs();		
		sessionMsgPrint(session, msg, args);
	}
	
	/**
	 * 优秀处理命令
	 * 
	 * @param session
	 * @param command
	 * @param intcp
	 * @return
	 */
	private boolean processCommandFirst(IoSession session, String command, 
			CommandInterpreter intcp, String cmdline) {
		// 退出独占
		if ("out".equals(command)) {
			_out(session);			
		}				
		// 强制性独占
		else if ("exclusion".equals(command)) {
			_exclusion(session);			
		}
		// 帮助
		else if ("help".equals(command)) {
			_help(session);			
		}
		// 所有telnet客户端信息
		else if ("who".equals(command) || "sessions".equals(command)) {
			_sessions(session);			
		}
		// 输出接口日志到控制端
		else if ("pl".equals(command)) {
			String bundleId = intcp.nextArgument();
			if (bundleId == null) {
				// 关闭原有的输出				
				if (!closeRsplcForSession(session)) {
					sessionMsgPrintln(session, "WARN: usage[ pl id [DEFAULT DEBUG INFO TRACE WARN FATAL ERROR] [[QUIET] [QUIET PACKAGES]]]");
				}
				return true;
			}
			
			String level = intcp.nextArgument();
			if (level == null) {
				level = "DEFAULT";
			}
			
			boolean quieted = false;
			if (level.equalsIgnoreCase("quiet")) {
				quieted = true;
				level = "DEFAULT";
			} else {
				String quiet = intcp.nextArgument();
				if (quiet != null && quiet.equalsIgnoreCase("quiet")) {// 安静
					quieted = true;
				}
			}
			
			// 忽略包列表
			String quietPackages = intcp.nextArgument();
			
			_printlogconsole(bundleId, level, session, quieted, quietPackages);
		}
		// 向所有人发送消息
		else if ("wall".equals(command)) {
			String message = null;
			if (cmdline.length() >= ("wall".length() + 1)) {
				message = cmdline.substring(cmdline.indexOf("wall") + "wall".length() + 1);
			}
			
			if (message == null) {
				sessionMsgPrintln(session, "WARN: usage[ wall 'messages']");
				return true;
			}
			_wall(session, message);
		}
		// 关闭指定接口的二进制日志记录
		else if ("streamlog".equals(command)) {
			String bundleId = intcp.nextArgument();
			String action = intcp.nextArgument();
			if (bundleId == null || action == null) {
				sessionMsgPrintln(session, "WARN: usage[ streamlog id [CLOSE OPEN]]");
				return true;
			}
			
			_streamlog(bundleId, action, session);
		}
		else if ("useradd".equalsIgnoreCase(command)) {// 增加用户	
			String username = StringUtil.trimWhiteToNull(intcp.nextArgument());
			String password = StringUtil.trimWhiteToNull(intcp.nextArgument());
			if (username == null || password == null) {
				sessionMsgPrintln(session, "USAGE: useradd 'username' 'password'");
				return true;
			}
			
			useradd(username, password);
			sessionMsgPrintln(session, "Add user '" + username + "' success.");
		}
        else if ("userdel".equalsIgnoreCase(command)) {// 删除用户
        	String username = StringUtil.trimWhiteToNull(intcp.nextArgument());
        	if (username == null) {
				sessionMsgPrintln(session, "USAGE: userdel 'username'");
				return true;
			}
			userdelete(username);
			sessionMsgPrintln(session, "Delete user '" + username + "' success.");
		}
        else if ("userchd".equalsIgnoreCase(command)) {// 用户赋权
        	String username = StringUtil.trimWhiteToNull(intcp.nextArgument());
        	String cmd = StringUtil.trimWhiteToNull(intcp.nextArgument());
        	String intfId = StringUtil.trimWhiteToNull(intcp.nextArgument());
        	if (username == null || cmd == null || intfId == null) {
				sessionMsgPrintln(session, "USAGE: userchd 'username' add/del/password 'intfId'[newpassword]");
				return true;
			}
        	
			if (userchmod(session, username, cmd, intfId)) {
			    sessionMsgPrintln(session, cmd + " " + intfId + " for user '" + username + "' success.");
			}
		}
        else if ("password".equalsIgnoreCase(command)) {// 修改密码        	
        	String oldpassword = StringUtil.trimWhiteToNull(intcp.nextArgument());
        	String newpassword = StringUtil.trimWhiteToNull(intcp.nextArgument());
        	
        	User user = (User)session.getAttribute(LOGIN);
        	String username = user.userName;
        	if (username == null || oldpassword == null || newpassword == null) {
        		sessionMsgPrintln(session, "USAGE: password 'oldpassword' 'newpassword'");
				return true;
        	}
        	        	
			if (password(session, username, oldpassword, newpassword, true)) {
				sessionMsgPrintln(session, " Change password for user '" + username + "' success.");
			}			
		} 
        else if ("down".equalsIgnoreCase(command)) {
        	String id = StringUtil.trimWhiteToNull(intcp.nextArgument());
        	_down(session, Long.valueOf(id));
        	sessionMsgPrintln(session, " Down session '" + id + "' success.");
        }
        else if ("users".equalsIgnoreCase(command)) {
        	String username = StringUtil.trimWhiteToNull(intcp.nextArgument());
        	_users(session, username);
        } 
        else if ("stp".equalsIgnoreCase(command)) {
        	_stp(session);
        } 
        else if (FrameworkConstants.CLUSTER_SWITCH.equalsIgnoreCase(command)) {
        	session.setAttribute(FrameworkConstants.CLUSTER_SWITCH, Boolean.TRUE);
        }		
		else {
			return false;
		}

		return true;
	}
	
	/**
	 * 控制台线程池ID
	 * 
	 * @param session
	 */
	private void _stp(IoSession session) {
		String sessionTpId = this.sessionThreadModelExecutor.getId();
		sessionMsgPrintln(session, "控制台线程池: " + sessionTpId);
				
		if (AutoInjectServiceBeanPostProcessor.PUBLISH_RS_TPE.size() > 0) {
			sessionMsgPrintln(session, "接口发布线程池： ");
			for (LogThreadPoolExecutor tpe : AutoInjectServiceBeanPostProcessor.PUBLISH_RS_TPE) {
				sessionMsgPrintln(session, tpe.getId() + "\t" + tpe.getName());
			}
		}		
	}
	
	/**
	 * 退出该session独占执行命令
	 * 
	 * @param session
	 */
	private void _out(IoSession session) {
		synchronized (execExclusionCmdSessions) {
			execExclusionCmdSessions.remove(session);
			session.removeAttribute(EXCLUSION_CMD);
		}
	}
	
	/**
	 * 强制性让其他session退出强制执行模式, 而让本身变成独占
	 * 
	 */
	private void _exclusion(IoSession session) {
		synchronized (execExclusionCmdSessions) {
			execExclusionCmdSessions.clear();
			session.setAttribute(EXCLUSION_CMD, execExclusionCmdSessions);
			execExclusionCmdSessions.put(session, System.currentTimeMillis());
		}
	}
	
	/**
	 * 是否独占
	 * 
	 * @param session
	 * @return
	 */
	private boolean isExclusionSession(IoSession session) {
		synchronized (execExclusionCmdSessions) {
			Long l = execExclusionCmdSessions.get(session);
            if (l != null) {
            	return true;
            }
		}
		
		return false;
	}
	
	/**
	 * 显示提示信息
	 * 
	 * @param session
	 */
	private void _help(IoSession session) {
		sessionMsgPrintln(session, "support gb2312 --modiby 20100422");
		sessionMsgPrintln(session, "out       -- exit to exclusion executing command.");
		sessionMsgPrintln(session, "exclusion -- force all the other session exit exclusion executing command mode.");
		sessionMsgPrintln(session, "sessions  -- print all the sessions using telnet.");
		sessionMsgPrintln(session, "who       -- print all the sessions using telnet, same with sessions");
		sessionMsgPrintln(session, "pl        -- print the special id log to the console");
		sessionMsgPrintln(session, "wall      -- send message to all the people who login the platform");
		sessionMsgPrintln(session, "find      -- find interface by name");
		sessionMsgPrintln(session, "fb        -- find bundle by bundle id or bundle name");
		sessionMsgPrintln(session, "fs        -- find spring service bundle by bundle id or bundle name");
		sessionMsgPrintln(session, "restart   -- restart the interface or bundle");
		sessionMsgPrintln(session, "streamlog -- close or open the stream log record for special interface");
		sessionMsgPrintln(session, "ss        -- print all the bundles state");
		sessionMsgPrintln(session, "rs        -- print all the interfaces,[rs [-l][-i][-f][id]]");
		sessionMsgPrintln(session, "start     -- start the bundle");
		sessionMsgPrintln(session, "stop      -- stop the bundle");
		sessionMsgPrintln(session, "sss       -- print all the spring bundles state");
		sessionMsgPrintln(session, "exit      -- exit the telnet login");
		sessionMsgPrintln(session, "ps        -- package state, for the import packages and export packages");
		sessionMsgPrintln(session, "info      -- print the bundle informations, services and packages");
		sessionMsgPrintln(session, "lt        -- print the tasks processing status");
		sessionMsgPrintln(session, "flush     -- flush the cache. USAGE: [flush id[all]], PRINT: [flush print [id]], FIND: [flush find [id] [expression]]");
		sessionMsgPrintln(session, "cs        -- close the session. USAGE: [cs 'session id']");
		sessionMsgPrintln(session, "st        -- simulate to send a task . USAGE: [st 'taskid' 'endpoint id' [name=value,...]] [-i controlid]");
		sessionMsgPrintln(session, "tp        -- print the threadpoolExecutors . USAGE: tp [contrlid][all][print/pt poolid][printStackTraceSys/pstsys theadsysid]\n" +
				"              [printStackTrace/pst poolthreadid][interrupt/it [-thread/-t/-threadsys/-tsys poolthreadid][-pool/-p poolid]]");
		sessionMsgPrintln(session, "useradd   -- add a user. USAGE: [useradd 'username' [password]]");
		sessionMsgPrintln(session, "userdel   -- delete a user. USAGE: [userdel 'username']");
		sessionMsgPrintln(session, "userchd   -- delete a user. USAGE: [userchd 'username' add/del/password 'intfId'[newpassword]]");
		sessionMsgPrintln(session, "password  -- alter password. USAGE: [password 'oldpassord' 'newpassword']");
		sessionMsgPrintln(session, "down      -- close the telnet session. USAGE: [down 'sessionid']");
		sessionMsgPrintln(session, "users     -- print all users. USAGE: [users]");
		sessionMsgPrintln(session, "aq        -- print the accept wait task queues. USAGE: [aq [endpoint[,endpoint]]]");
		sessionMsgPrintln(session, "tq        -- print the task queues. USAGE: [tq [endpoint[,endpoint]]]");
		sessionMsgPrintln(session, "nor       -- print no result tasks. USAGE: [nor rsid");
		sessionMsgPrintln(session, "encrypt   -- translate to encrypt string. USAGE: [encrypt str]");
		sessionMsgPrintln(session, "decrypt   -- translate from encrypt string. USAGE: [decrypt str]");
		sessionMsgPrintln(session, "stp       -- print the console session threadpool id. USAGE: [stp]");
		sessionMsgPrintln(session, "pbs       -- print the pending recv session buffer. USAGE: [pbs 'session id']");
		sessionMsgPrintln(session, "ft        -- find the thread by name. USAGE: [ft 'threadname']");
		sessionMsgPrintln(session, "ses       -- print the session status. USAGE: [ses 'constrol id']");
		sessionMsgPrintln(session, "cl        -- the cluster commands. USAGE: [cl active [id]]/print [id]/clear");
	}
	
	/**
	 * 输出所有正在使用telnet的客户端信息
	 * 
	 */
	private void _sessions(IoSession session) {		
        Set<IoSession> ss = new HashSet<IoSession>(session.getService().getManagedSessions(session.getServiceAddress()));
		if (ss != null) {
			sessionMsgPrintln(session, "total telnet client number: " + ss.size());
			if (ss.size() > 0) {
				sessionMsgPrintln(session, "-------------------------------");
				for (IoSession s : ss) {
					String msg = "sesionId: " + getSessionId(s) + ", " + 
					          s.getAttribute(LOGIN) + ", " + s.toString();
					if (isExclusionSession(s)) {
						msg = msg + " ( Exclusion Mode )";
					}
					
					if (s.getAttribute(FrameworkConstants.CLUSTER_SWITCH) != null) {
						msg = msg + " ( CLUSTER USER )";
					}
					
					if (session == s) {
						msg = msg + " ( YOU )";
					}
					
					sessionMsgPrintln(session, msg);
				}
				sessionMsgPrintln(session, "-------------------------------");
			}			
		}		
	}
	
	private void _users(IoSession session, String username) {
		List<UserEncryption> ues = getCurrentUserEncryptions();		
		if (ues != null) {				
			for (UserEncryption ue : ues) {
				if (username == null) {
					sessionMsgPrintln(session, "username: " + ue.userName + ", execs: " + ue.execIntfs);
				} else if (username.equalsIgnoreCase(ue.userName)) {
					sessionMsgPrintln(session, "username: " + ue.userName + ", execs: " + ue.execIntfs);
					break;
				}				
			}
		}
	}
	
	private void _down(IoSession currentSession, long id) {
		IoSession session = getSessionFrom(currentSession, id);
		if (session != null) {
			session.close();
		}
	}
	
	/**
	 * 向控制台输出日志
	 * 
	 * @param bundleId
	 * @param level
	 * @param session
	 */
	@SuppressWarnings("unchecked")
	protected void _printlogconsole(String bundleId, String level, final IoSession session, boolean quieted, String quietPackages) {
		RegisteredServiceFindService findService = getRegisteredServiceFindService();
		if (findService == null) {
			sessionMsgPrintln(session, "WARN: Can't print log to console, for the RegisteredServiceFindService can't be found.");
			return;
		}
		
		// 关闭原有的输出
		closeRsplcForSession(session);
		
		List<RegisterServicePrintlogConsole> rsplcs = new ArrayList<RegisterServicePrintlogConsole>();
		try {
			if ("all".equals(bundleId)) { // 输出所有的接口日志
				Collection<RegisteredService> rss = findService.getRegisteredServices();
				if (rss != null) {
					for (RegisteredService rs : rss) {
						rsplcs.add(createRsplc(rs, level, session, quieted, quietPackages));
					}
				}
			} else {
				RegisteredService rs = findService.getRegisteredService(Long.parseLong(bundleId));
				if (rs == null) {
					sessionMsgPrintln(session, "WARN: Can't find interface with the control id " + bundleId);
					return;
				}

				rsplcs.add(createRsplc(rs, level, session, quieted, quietPackages));
			}
		} finally {
			session.setAttribute(REGISTERSERVICEPRINTLOGCONSOLE_KEY, rsplcs);
		}
	}
	
	/**
	 * 关闭控制台上的现有日志
	 * 
	 * @param session
	 */
	@SuppressWarnings("unchecked")
	private boolean closeRsplcForSession(IoSession session) {
		List<RegisterServicePrintlogConsole> rsplcsOld = (List<RegisterServicePrintlogConsole>)session.getAttribute(REGISTERSERVICEPRINTLOGCONSOLE_KEY);
		if (rsplcsOld != null) {
			for (RegisterServicePrintlogConsole rsplcOld : rsplcsOld) {
				sessionMsgPrintln(session, "WARN: PrintlogConsole closed for .... " + rsplcOld.getRegisteredService());
				rsplcOld.close();
			}			
			session.removeAttribute(REGISTERSERVICEPRINTLOGCONSOLE_KEY);
			
			return true;
		}
		
		return false;
	}
	
	/**
	 * 关闭指定接口上的二进制日志输出
	 * 
	 * @param bundleId
	 * @param action
	 */
	protected void _streamlog(String bundleId, String action, IoSession session) {
		RegisteredServiceFindService findService = getRegisteredServiceFindService();
		if (findService == null) {
			sessionMsgPrintln(session, "WARN: Can't execute 'streamlog' command, for the RegisteredServiceFindService can't be found.");
			return;
		}
		
		RegisteredService rs = findService.getRegisteredService(Long.parseLong(bundleId));
		if (rs == null) {
			sessionMsgPrintln(session, "WARN: Can't find interface with the control id " + bundleId);
			return;
		}
		
		if (!(rs instanceof AbstractSocketService)) { // 判断是否SOCKET类接口
			// 不是
			sessionMsgPrintln(session, "WARN: the interface type is not 'SOCKET'");
			return;
		}
		
		if (action.equalsIgnoreCase("CLOSE")) {// 关闭
			rs.getAttributes().setAttribute(FrameworkConstants.STREAM_LOG_NOT_WRITED, "true");
			// 同时将正在运行的session关闭写二进制功能
			Collection<IoSession> sessions = ((AbstractSocketService)rs).getManagedSessions();
			if (sessions != null && sessions.size() > 0) {// 有session连接
				for (IoSession s : sessions) {
					s.setAttribute(FrameworkConstants.STREAM_LOG_NOT_WRITED, "true");
				}
			}
		} else if (action.equalsIgnoreCase("OPEN")) {// 打开
			rs.getAttributes().removeAttribute(FrameworkConstants.STREAM_LOG_NOT_WRITED);
			// 同时将正在运行的session打开写二进制功能
			Collection<IoSession> sessions = ((AbstractSocketService)rs).getManagedSessions();
			if (sessions != null && sessions.size() > 0) {// 有session连接
				for (IoSession s : sessions) {
					s.removeAttribute(FrameworkConstants.STREAM_LOG_NOT_WRITED);
				}
			}
		} else {
			sessionMsgPrintln(session, "WARN: Invalid argument for action, must be in [CLOSE OPEN]");
			return;
		}
	}
	
	/**
	 * 创建日志
	 * 
	 * @param rs
	 * @param level
	 * @param session
	 * @return
	 */
	private RegisterServicePrintlogConsole createRsplc(RegisteredService rs, String level, final IoSession session, boolean quieted, String quietPackages) {
		RegisterServicePrintlogConsole rsplc = new RegisterServicePrintlogConsole(rs, level, session, new SessionOutput() {
			public void write(Object o) {
				sessionMsgPrint(session, o, null);
			}
		}, quieted, quietPackages);
		
		rsplc.print(); // 开始输出
		
		String msg = "PrintlogConsole pintting for .... " + rs;
		if (quieted) {
			msg = msg + " [with quiet]";
			if (quietPackages != null) {
				msg = msg + " for " + quietPackages;
			}
		}
		
		sessionMsgPrintln(session, msg);
		
		return rsplc;
	}
	
	/**
	 * 发送信息到当前登录到平台上的所有用户
	 * 
	 * @param session
	 */
	private void _wall(IoSession session, String message) {	
		User user = (User)session.getAttribute(LOGIN);
        Set<IoSession> ss = session.getService().getManagedSessions(session.getServiceAddress());
		if (ss != null) {
			for (IoSession s : ss) {
				sessionMsgPrintln(s, "[WALL] " + user.userName + " : " + message);
			}
		}
	}
	
	/**
	 * 输出一行
	 * 
	 * @param session
	 * @param o
	 */
	protected void sessionMsgPrintln(IoSession session, Object o) {
		sessionPrint(session, o, null, true, null);
	}
	
	/**
	 * 输出
	 * 
	 * @param session
	 * @param o
	 */
	protected void sessionMsgPrint(IoSession session, Object o, String[] args) {
		sessionPrint(session, o, null, false, null);
	}
	
	/**
	 * 输出, 包括异常
	 * 
	 * @param session
	 * @param o
	 * @param t
	 * @param newline
	 */
	protected void sessionPrint(IoSession session, Object o, Throwable t, 
			boolean newline, String[] args) {
		o = o == null ? " " : o;
		String msg = o.toString();		
		if (newline) {
			msg = msg + "\n";
		}
		
		if (t != null) {
			StringWriter sw = new StringWriter();
			t.printStackTrace(new PrintWriter(sw));
			msg = msg + sw.toString();
		}
		
		if (msg != null) {
			msg = msg.replace(NEWLINE, "\n");
			msg = msg.replace("\n", NEWLINE);
			
			if (session.getAttribute(FrameworkConstants.CLUSTER_SWITCH) != null) {
				if (args != null && args.length > 0) {
					for (String arg : args) {
						Task ct = ClusterCommandSupport.createCommandTask(arg);
						if (ct != null) {
							// TODO
						}
					}
				}
			}

			session.write(msg);// 发送
		}
	}
	
	/**
	 * 过滤不允许多人执行的命令
	 * 
	 * @param command
	 * @return
	 */
	private boolean filterCommandExecute(String command) {
		command = StringUtil.trimWhiteToNull(command);
		
		if ("start".equals(command) 
				|| "stop".equals(command)
				|| "install".equals(command)
				|| "uninstall".equals(command)
				|| "refresh".equals(command)
				|| "update".equals(command)
				|| "restart".equals(command)
				) {
			return false;
		}
		
		if ("useradd".equals(command)
				|| "userdel".equals(command)
				|| "userchd".equals(command)
				|| "password".equals(command)) {
			return false;
		}
		
		return true;
	}
	
	private boolean checkForCmdPermission(String username, String command, String cmdline) {
		if ("useradd".equalsIgnoreCase(command) 
				|| "userdel".equalsIgnoreCase(command)
				|| "userchd".equalsIgnoreCase(command)
				|| "down".equalsIgnoreCase(command)
				|| "encrypt".equalsIgnoreCase(command)
				|| "decrypt".equalsIgnoreCase(command)
				) {
			if ("admin".equalsIgnoreCase(username)) {
				return true;
			}
			return false;
		}
		
		if ("start".equals(command) 
				|| "stop".equals(command)
				|| "install".equals(command)
				|| "uninstall".equals(command)
				|| "refresh".equals(command)
				|| "update".equals(command)
				|| "restart".equals(command)
				) {
			String rsId = cmdline.substring(cmdline.indexOf(command) + command.length() + 1);
			return checkUserCmdPermission(username, command, rsId);			
		}
		
		return true;
	}
	
	/**
	 * 获取独占
	 * 
	 * @param session
	 * @return
	 */
	private boolean getExecuteExclusion(IoSession session, String command) {
		synchronized (execExclusionCmdSessions) {
			// 先查看是否本身独占
			if (session.getAttribute(EXCLUSION_CMD) != null && execExclusionCmdSessions.get(session) != null) {
				return true;
			}
			
			// 不是, 则继续检查
			if (execExclusionCmdSessions.isEmpty() || execExclusionCmdSessions.size() == 0) { // 没有独占, 则占用
				execExclusionCmdSessions.put(session, System.currentTimeMillis());
				session.setAttribute(EXCLUSION_CMD, execExclusionCmdSessions);
				return true;
			} else {
				// 占用
				for (Iterator<IoSession> it = execExclusionCmdSessions.keySet().iterator(); it.hasNext();) {
					IoSession s = it.next();
					Long time = execExclusionCmdSessions.get(s);
					// 检测时间是否超时
					boolean isTimeout = (System.currentTimeMillis() - time) > EXCLUSION_TIMEOUT;
					if (isTimeout) {
						// 超时
						it.remove();
					}
				}
				
				// 重新检测独占
				if (execExclusionCmdSessions.isEmpty() || execExclusionCmdSessions.size() == 0) {
					// 没有
					execExclusionCmdSessions.put(session, System.currentTimeMillis());
					session.setAttribute(EXCLUSION_CMD, execExclusionCmdSessions);
					return true;
				}
			}
		}
		
		sessionMsgPrintln(session, NEWLINE + "WARN: Session: " + execExclusionCmdSessions.keySet().iterator().next()
				+ " is executing exclusion, you can't execute command \"" + command + "\" in the moment.");
		
		return false;
	}
}
